import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express from 'express';
import { z } from 'zod';
// import { calculate } from './calculator.ts';
// import { CalculateRequest, CalculateResponse } from './types.ts';


/** 计算请求参数类型 */
export interface CalculateRequest {
  operation: 'add' | 'subtract' | 'multiply' | 'divide';
  a: number;
  b: number;
}

/** 计算响应结果类型 */
export interface CalculateResponse {
  success: boolean;
  result?: number;
  error?: string;
}

/** 标准输入输出消息类型 */
export type StdioMessage = 
  | { type: 'request'; data: CalculateRequest }
  | { type: 'response'; data: CalculateResponse }
  | { type: 'error'; message: string };

/**
 * 执行计算逻辑
 * @param request 计算请求参数
 * @returns 计算结果响应
 */
export function calculate(request: CalculateRequest): CalculateResponse {
  const { operation, a, b } = request;

  // 输入验证
  if (isNaN(a) || isNaN(b)) {
    return {
      success: false,
      error: 'Invalid input: a and b must be numbers'
    };
  }

  try {
    switch (operation) {
      case 'add':
        return { success: true, result: a + b };
      case 'subtract':
        return { success: true, result: a - b };
      case 'multiply':
        return { success: true, result: a * b };
      case 'divide':
        if (b === 0) {
          return { success: false, error: 'Division by zero is not allowed' };
        }
        return { success: true, result: a / b };
      default:
        return {
          success: false,
          error: `Unsupported operation: ${operation}. Use add/subtract/multiply/divide`
        };
    }
  } catch (err) {
    return {
      success: false,
      error: `Calculation failed: ${(err as Error).message}`
    };
  }
}

// Create an MCP server
const server = new McpServer({
    name: 'calculator-server',
    version: '1.0.0'
});

// Add addition tool
server.registerTool(
    'add',
    {
        title: 'Addition Tool',
        description: 'Add two numbers',
        inputSchema: { a: z.number(), b: z.number() },
        outputSchema: { success: z.boolean(), result: z.number().optional(), error: z.string().optional() }
    },
    async ({ a, b }) => {
        const request: CalculateRequest = { operation: 'add', a, b };
        const result: CalculateResponse = calculate(request);
        return {
            content: [{ type: 'text', text: JSON.stringify(result) }],
            structuredContent: result as unknown as { [key: string]: unknown }
        };
    }
);

// Add subtraction tool
server.registerTool(
    'subtract',
    {
        title: 'Subtraction Tool',
        description: 'Subtract two numbers',
        inputSchema: { a: z.number(), b: z.number() },
        outputSchema: { success: z.boolean(), result: z.number().optional(), error: z.string().optional() }
    },
    async ({ a, b }) => {
        const request: CalculateRequest = { operation: 'subtract', a, b };
        const result: CalculateResponse = calculate(request);
        return {
            content: [{ type: 'text', text: JSON.stringify(result) }],
            structuredContent: result as unknown as { [key: string]: unknown }
        };
    }
);

// Add multiplication tool
server.registerTool(
    'multiply',
    {
        title: 'Multiplication Tool',
        description: 'Multiply two numbers',
        inputSchema: { a: z.number(), b: z.number() },
        outputSchema: { success: z.boolean(), result: z.number().optional(), error: z.string().optional() }
    },
    async ({ a, b }) => {
        const request: CalculateRequest = { operation: 'multiply', a, b };
        const result: CalculateResponse = calculate(request);
        return {
            content: [{ type: 'text', text: JSON.stringify(result) }],
            structuredContent: result as unknown as { [key: string]: unknown }
        };
    }
);

// Add division tool
server.registerTool(
    'divide',
    {
        title: 'Division Tool',
        description: 'Divide two numbers',
        inputSchema: { a: z.number(), b: z.number() },
        outputSchema: { success: z.boolean(), result: z.number().optional(), error: z.string().optional() }
    },
    async ({ a, b }) => {
        const request: CalculateRequest = { operation: 'divide', a, b };
        const result: CalculateResponse = calculate(request);
        return {
            content: [{ type: 'text', text: JSON.stringify(result) }],
            structuredContent: result as unknown as { [key: string]: unknown }
        };
    }
);

// Add a dynamic greeting resource
server.registerResource(
    'greeting',
    new ResourceTemplate('greeting://{name}', { list: undefined }),
    {
        title: 'Greeting Resource', // Display name for UI
        description: 'Dynamic greeting generator'
    },
    async (uri, { name }) => ({
        contents: [
            {
                uri: uri.href,
                text: `Hello, ${name}!`
            }
        ]
    })
);

// Set up Express and HTTP transport
const app = express();
app.use(express.json());

app.post('/mcp', async (req, res) => {
    // Create a new transport for each request to prevent request ID collisions
    const transport = new StreamableHTTPServerTransport({
        sessionIdGenerator: undefined,
        enableJsonResponse: true
    });

    res.on('close', () => {
        transport.close();
    });

    await server.connect(transport);
    await transport.handleRequest(req, res, req.body);
});

const port = parseInt(process.env.PORT || '3000');
app.listen(port, () => {
    console.log(`Demo MCP Server running on http://localhost:${port}/mcp`);
}).on('error', error => {
    console.error('Server error:', error);
    process.exit(1);
});